`timescale 1ns / 1ps
module dma_sender(
        input wire      clk,
		input wire      rst_n,

        input wire[15:0] trans_num,
        input wire[15:0] start_postion,

		input wire[31:0] s_tdata,
        input wire[3:0]  s_tkeep,
		input wire	     s_tvalid,
		output wire      s_tready,

		output wire[31:0] m_tdata,
		output wire		  m_tvalid,
		input  wire       m_tready,
		output reg        m_tlast,
        output wire[3:0]  m_tkeep,
        output reg[15:0] readed_data_count
    );

    reg trans_full;
    reg trans_start;
    reg[15:0] TN;
    reg[15:0] TNN;

    assign m_tvalid = trans_full ? 1'b0 : trans_start ? s_tvalid : 1'b1;
    assign s_tready = trans_full ? 1'b0 : trans_start ? m_tready : 1'b0;
    assign m_tkeep = m_tvalid ? s_tkeep : 4'h0;
    assign m_tdata = trans_start ? s_tdata : readed_data_count; 

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            TNN <= 0;
            TN <= 0;
        end else begin
            TN <= trans_num + start_postion;
            TNN <= TN - 1;
        end
    end

    always @(negedge clk or negedge rst_n) begin
        if (!rst_n) begin
            readed_data_count <= 0;
        end else if (readed_data_count < TN && m_tvalid && m_tready) begin
            readed_data_count <= readed_data_count + 1;
        end else if(readed_data_count >= TN && m_tready == 0)begin
            readed_data_count <= 0;
        end else begin
            readed_data_count <= readed_data_count;
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            trans_full <= 0;
            trans_start <= 0;
            m_tlast <= 0;
        end else if(readed_data_count == 0) begin
            trans_full <= 0;
            trans_start <= 0;
            m_tlast <= 0; 
        end else if(readed_data_count == start_postion) begin
            trans_full <= 0;
            trans_start <= 1;
            m_tlast <= 0;            
        end else if(readed_data_count == TNN && m_tready) begin
            trans_full <= 0;
            trans_start <= 1;
            m_tlast <= 1;
        end else if(readed_data_count == TN)begin
            trans_full <= 1;
            trans_start <= 1;
            m_tlast <= m_tlast;
        end else begin
            trans_start <= trans_start;
            trans_full <= trans_full;
            m_tlast <= m_tlast;
        end
    end

endmodule
